/*
 * Solver.cpp
 *
 *  Created on: Oct 22, 2012
 *      Author: pedro
 */

#include "Solver.h"

vector<Problem> Solver::solveProblem(Graph &graph, Problem &problem, Solution &bestUpperBound, int *modifyed)
{
	vector<Problem> newProblems;

	if(!bestUpperBound.hasCost() || (bestUpperBound.hasCost() && problem.getLowerBound() < bestUpperBound.getCost()) )
	{

		Graph *reducedGraph = Adapter::applyConstraints(graph,problem);

		Hungarian h ( *reducedGraph );

		delete reducedGraph;

		vector<int> solutionVector = h.solve();

		solutionVector = Adapter::expandSolution(solutionVector,problem);

		Solution solution ( solutionVector );

		solution.calculateCost(graph);

		if(!bestUpperBound.hasCost() || (bestUpperBound.hasCost() && bestUpperBound.getCost() > solution.getCost()))
		{

			if(solution.isGood() == false)
			{

				int *cycleInf = new int (NO_CYCLE);
				Index  i = solution.getCycleEdge(problem,cycleInf);

				if(i.getX() == 0 && i.getY() == 0)
				{
				}
				else
				{

					problem.addConstraint(i.getX(),i.getY(),REMOVE_EDGE);

					if(problem.checkFeasible(*cycleInf,REMOVED))
					{
						problem.setLowerBound(solution.getCost());
						newProblems.push_back(problem);
					}

					problem.addConstraint(i.getX(),i.getY(),FIX_EDGE);

					if(problem.checkFeasible(*cycleInf,FIXED))
					{
						problem.setLowerBound(solution.getCost());
						newProblems.push_back(problem);
					}
				}

				delete cycleInf;

			}
			else
			{
				if(!bestUpperBound.hasCost() || (bestUpperBound.hasCost() && bestUpperBound.getCost() > solution.getCost()))
				{
					*modifyed = 1;
					bestUpperBound = solution;
				}
			}
		}
	}

	return newProblems;

}

